<template>
  <g
    class="text-label"
    :data-label-id="id"
    :style="labelStyle"
    @dblclick="handleDblclick"
    @mousedown="handleMousedown"
    @mouseup="handleMouseup"
    @mouseenter="handleMouseenter"
    @mouseleave="handleMouseleave">
    <!-- <rect
      ref="rect"
      rx="2"
      ry="2"
      :x="x - offsetX"
      :y="y - fontSize"
      :width="width"
      :height="height"
      :fill="bgColor"
      :stroke="bgColor"
    /> -->
    <text>
      <tspan
        onselectstart="return false"
        ref="tspan"
        :x="x - offsetX"
        :y="y"
        :fill="fgColor"></tspan>
    </text>
  </g>
</template>

<script>
export default {
  props: {
    disabled: Boolean,
    x: Number,
    y: Number,
    text: String,
    type: String,
    bgColor: String,
    fgColor: String,
    fontSize: Number,
    rowStart: Number,
    rowEnd: Number,
    id: String,
    entityText: String,
    status: String
  },

  inject: [
    'handleEditEntity',
    'handleLabelPosition',
    'setStatus',
    'setRelationLinePosition',
    'setRelationDialogEntity',
    'getRelationDialogEntity',
    'testRelations',
    'getReselectId'
  ],

  data () {
    return {
      width: 0,
      offsetX: 0,
      rectX: 0,
      rectY: 0,
      // label 标签的状态
      labelStatus: '',
    }
  },

  computed: {
    // tooltip () {
    //   return {
    //     content: `
    //     <div class="marking-tooltip">
    //       <div>
    //         <span>${this.text}</span>
    //         <span>ID: ${this.id}</span>
    //       </div>
    //       <div>"${this.entityText}"</div>
    //     </div>
    //     `,
    //     html: true
    //   }
    // },
    height () {
      return this.fontSize * 1.25
    },
    labelStyle () {
      let outlineColor = this.fgColor
      let outlineWidth = '0'
      if (this.labelStatus === 'setting' || this.labelStatus === 'choose') {
        outlineWidth = '2px'
      } else if (this.labelStatus === 'disable') {
        outlineColor = '#F82418'
        outlineWidth = '2px'
      }
      return {
        fontSize: this.fontSize + 'px',
        borderRadius: '2px',
        outlineStyle: 'solid',
        outlineColor,
        outlineWidth
      }
    }
  },

  watch: {
    status () {
      if (this.status === 'reselect-relation' && this.getReselectId() === this.id) {
        this.handleMousedown(null, true)
      }
    }
  },

  methods: {
    getPosition () {
      this.width = this.$refs.tspan.getBoundingClientRect().width
      this.offsetX = this.width / 2
      // 判断是否超出 svg 边界
      if (this.x - this.offsetX < this.rowStart) {
        this.offsetX = this.x - this.rowStart
      }
      if (this.x - this.offsetX + this.width > this.rowEnd) {
        this.offsetX = this.x + this.width - this.rowEnd
      }

      // 发送坐标信息用于锁定 relation
      this.handleLabelPosition({
        id: this.id,
        x: this.x - this.offsetX,
        y: this.y - this.fontSize,
        width: this.width
      })
    },
    handleDblclick (e) {
      if (this.disabled) return

      this.handleEditEntity(this.id)
    },
    handleMouseenter () {
      if (this.labelStatus === 'setting') return
      if (this.status === 'set-relation' || this.status === 'reselect-relation') {
        const from = this.getRelationDialogEntity()[0]
        const relation = this.testRelations(from && from.type, this.type)
        if (relation.length > 0) {
          this.labelStatus = 'choose'
        } else {
          this.labelStatus = 'disable'
        }
      }
    },
    handleMouseleave () {
      if (this.labelStatus === 'setting') return
      if (this.status === 'set-relation' || this.status === 'reselect-relation') {
        this.labelStatus = ''
      }
    },
    handleMouseup () {
      if (this.labelStatus === 'disable') {
        this.labelStatus = ''
      }
      if (this.labelStatus === 'choose') {
        this.setRelationDialogEntity('to', {
          type: this.type,
          text: this.text,
          id: this.id,
          entityText: this.entityText
        })
        this.labelStatus = ''
      }
    },
    handleMousedown (e, force) {
      if (this.disabled) return

      if (this.status !== '' && !force) return
      if (!force) {
        this.setStatus('set-relation')
        this.labelStatus = 'setting'
      }
      this.setRelationDialogEntity('from', {
        type: this.type,
        text: this.text,
        id: this.id,
        entityText: this.entityText
      })
      // edge 中不支持 x, y 这里需要用 left, top
      const { left, top } = this.$refs.rect.getBoundingClientRect()
      this.rectX = left
      this.rectY = top
      document.addEventListener('mousemove', this.dragHandler)
      document.addEventListener('mouseup', this.DocumentMouseUp)
    },
    dragHandler (e) {
      // 禁止默认事件，解决 firefox 下拖拽会选中文本
      e.preventDefault()
      this.setRelationLinePosition(this.getRelationLinePosition(e.clientX, e.clientY))
    },
    DocumentMouseUp(e) {
      this.setStatus('')
      this.labelStatus = ''
      this.setRelationLinePosition(null)
      document.removeEventListener('mousemove', this.dragHandler)
      document.removeEventListener('mouseup', this.DocumentMouseUp)
    },
    getRelationLinePosition (mouseX, mouseY) {
      const { x, y, rectX, rectY, offsetX, width, fontSize } = this
      const x1 = x - offsetX + width / 2
      const y1 = y - fontSize
      const x2 = x - offsetX + mouseX - rectX
      const y2 = y1 + mouseY - rectY
      return [x1, y1, x2, y2]
    }
  },

  mounted () {
    this.getPosition()
  }
}
</script>

<style>
</style>